﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics;
using System.Runtime.InteropServices;
using System.Windows.Forms;
using Assist;
using Autodesk.Revit.ApplicationServices;
using Autodesk.Revit.DB;
using Autodesk.Revit.Exceptions;
using Autodesk.Revit.UI;
using Autodesk.Revit.UI.Selection;
using YArchitech.Controls;
using YArchitech.LIB;
using YArchitech.Revit;
using YRevitJig;
using ModelChecking.ModelValidation.FireCompartment;

namespace ModelChecking.ModelValidation.Utils
{
	public class GetDistanceTempleCmd
	{
		[DllImport("user32.dll", EntryPoint = "SendMessageA")]
		public static extern int SendMessage(IntPtr hwnd, int wMsg, IntPtr wParam, IntPtr lParam);

		public Result Execute(int inputIndex, ExternalCommandData commandData, ref string message, ElementSet elements)
		{
			Transaction transaction = null;
			UIApplication application = commandData.Application;
            Autodesk.Revit.ApplicationServices.Application application2 = application.Application;
			Document document = application.ActiveUIDocument.Document;
			UIDocument activeUIDocument = commandData.Application.ActiveUIDocument;
			if (!YJKRevitTools.ViewCheck(activeUIDocument, new List<ViewType>
			{
				(ViewType)1,
				(ViewType)2
			}))
			{
				return Autodesk.Revit.UI.Result.Cancelled;
			}
			if (GetDistanceTempleCmd.hWndRevit == null)
			{
				Process currentProcess = Process.GetCurrentProcess();
				IntPtr mainWindowHandle = currentProcess.MainWindowHandle;
				GetDistanceTempleCmd.hWndRevit = new YJKWindowHandle(mainWindowHandle);
			}
			DistanceXMLLoader distanceXMLLoader = new DistanceXMLLoader();
			string inputResultFormName;
			string inputDataPath;
			if (!distanceXMLLoader.TryGetValue(inputIndex, out inputResultFormName, out inputDataPath))
			{
				YJKMessageBox.Show("读取配置文件失败!");
				return Autodesk.Revit.UI.Result.Succeeded;
			}
			DlgGetDistance dlgGetDistance = new DlgGetDistance(inputResultFormName, inputDataPath);
			ElementSet elementSet = new ElementSet();
			ElementSet elemSetDimArrow = new ElementSet();
			bool bDelete = true;
			dlgGetDistance.Show(GetDistanceTempleCmd.hWndRevit);
			int wMsg = 7;
			GetDistanceTempleCmd.SendMessage(GetDistanceTempleCmd.hWndRevit.Handle, wMsg, IntPtr.Zero, IntPtr.Zero);
			transaction = new Transaction(document, "绘制折线");
			transaction.Start();
			Selection selection = activeUIDocument.Selection;
			Result result;
			using (XLineJig xlineJig = new XLineJig(activeUIDocument))
			{
				try
				{
					XYZ xyz = selection.PickPoint("请选择绘制线段的起点：");
					XYZ xyz2 = new XYZ(xyz.X, xyz.Y, xyz.Z);
					int num = 0;
					List<XYZ> list = new List<XYZ>();
					list.Add(xyz);
					for (;;)
					{
						try
						{
							bDelete = !dlgGetDistance.cbDim.Checked;
							if (dlgGetDistance.Visible)
							{
								ViewAssist.ViewValidating(activeUIDocument.Document, activeUIDocument.ActiveView);
								xlineJig.StartPoint = xyz;
								XYZ xyz3 = xlineJig.PickEndPoint(xyz, "请选择绘制线段的下一点：");
								if (xyz.IsAlmostEqualTo(xyz3))
								{
									MessageBox.Show("不能选择两个重合的点！", "盈建科提示", MessageBoxButtons.OK, MessageBoxIcon.Asterisk);
								}
								else
								{
									list.Add(xyz3);
									DetailLine detailLine = YJKRevitTools.DrawDetailLine(document, xyz, xyz3);
									elementSet.Insert(detailLine);
									num++;
									double distance = Math.Round((detailLine.Location as LocationCurve).Curve.Length * 0.3048, 3);
									if (num % 2 == 0)
									{
										Curve curve = (detailLine.Location as LocationCurve).Curve;
									}
									else if (num % 2 == 1)
									{
										Curve curve2 = (detailLine.Location as LocationCurve).Curve;
									}
									xyz = xyz3;
									dlgGetDistance.ResetResult(distance);
									bool flag = dlgGetDistance.DimOrNot();
									if (flag)
									{
										this.CreateEndArrow(elementSet, application, ref elemSetDimArrow);
									}
									if (!xyz2.IsAlmostEqualTo(xyz3))
									{
										continue;
									}
									list.RemoveAt(list.Count - 1);
									double dArea = Geometry.PloygonArea(list);
									dArea = UnitConvert.AreaConverFromAPI(document, dArea);
									XYZ origin = selection.PickPoint("请选择标注面积和周长的点");
                                    document.GetTextNode(document.ActiveView, origin, XYZ.BasisX, XYZ.BasisY, 0.24384000000000003, (TextAlignFlags)64, string.Concat(new string[]
									{
										"周长：",
										dlgGetDistance.DimText(),
										" \n面积：",
										dArea.ToString("0.000"),
										" ㎡"
									}));
								}
							}
						}
						catch (Autodesk.Revit.Exceptions.OperationCanceledException)
						{
						}
						break;
					}
					document.Regenerate();
					transaction.Commit();
					dlgGetDistance.Close();
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
				catch (Exception)
				{
					this.DeleteDimAndLine(bDelete, elementSet, elemSetDimArrow, application);
					if (dlgGetDistance.DimOrNot())
					{
						this.DrawDimension(dlgGetDistance.DimText(), elemSetDimArrow, application);
					}
					dlgGetDistance.Close();
					transaction.Commit();
					result = Autodesk.Revit.UI.Result.Succeeded;
				}
				finally
				{
                    if (transaction != null && (int)transaction.GetStatus() != 3)
					{
						dlgGetDistance.Close();
						transaction.RollBack();
					}
					if (xlineJig != null)
					{
						xlineJig.Dispose();
					}
				}
			}
			return result;
		}

		private bool DrawDimension(string strDimText, ElementSet elemSetDimArrow, UIApplication uiApp)
		{
			Document document = uiApp.ActiveUIDocument.Document;
			Selection selection = uiApp.ActiveUIDocument.Selection;
			try
			{
				XYZ origin = selection.PickPoint("请选择标注的点");
				XYZ basisX = XYZ.BasisX;
				XYZ basisY = XYZ.BasisY;
                TextNote textNode = document.GetTextNode(document.ActiveView, origin, XYZ.BasisX, XYZ.BasisY, 0.24384000000000003, (TextAlignFlags)1152, strDimText);
				elemSetDimArrow.Insert(textNode);
			}
			catch (Exception)
			{
				return false;
			}
			return true;
		}

		private bool DeleteDimAndLine(bool bDelete, ElementSet detailLines, ElementSet elemSetDimArrow, UIApplication uiApp)
		{
			if (!bDelete)
			{
				return false;
			}
			if (detailLines.Size < 1)
			{
				return false;
			}
			IEnumerator enumerator = detailLines.GetEnumerator();
			bool flag = enumerator.MoveNext();
			while (flag)
			{
				Element element = enumerator.Current as Element;
				uiApp.ActiveUIDocument.Document.Delete(element.Id);
				flag = enumerator.MoveNext();
			}
			enumerator = elemSetDimArrow.GetEnumerator();
			flag = enumerator.MoveNext();
			while (flag)
			{
				Element element2 = enumerator.Current as Element;
				uiApp.ActiveUIDocument.Document.Delete(element2.Id);
				flag = enumerator.MoveNext();
			}
			return true;
		}

		private void GetDimTextAngle(XYZ ptRef, ElementSet lines, UIApplication uiApp, ref XYZ xVec, ref XYZ yVec)
		{
			double num = 10000.0;
			DetailLine detailLine = null;
			IEnumerator enumerator = lines.GetEnumerator();
			bool flag = enumerator.MoveNext();
			while (flag)
			{
				Element element = enumerator.Current as Element;
				DetailLine detailLine2 = element as DetailLine;
				XYZ closestPointTo = CurveAssistFunc.GetClosestPointTo(uiApp, detailLine2.GeometryCurve, ptRef, false);
				if (closestPointTo != null)
				{
					double num2 = closestPointTo.DistanceTo(ptRef);
					if (num2 < num)
					{
						detailLine = detailLine2;
						num = num2;
					}
				}
				flag = enumerator.MoveNext();
			}
			xVec = detailLine.GeometryCurve.GetEndPoint(1) - detailLine.GeometryCurve.GetEndPoint(0);
			yVec = AxisAssistFunc.RotateTo(xVec, Math.PI*.5, XYZ.BasisZ);
		}

		private void CreateEndArrow(ElementSet lines, UIApplication uiApp, ref ElementSet elemSetDim)
		{
			double num = 5.0;
			DetailLine detailLine = null;
			IEnumerator enumerator = lines.GetEnumerator();
			bool flag = enumerator.MoveNext();
			while (flag)
			{
				Element element = enumerator.Current as Element;
				detailLine = (element as DetailLine);
				flag = enumerator.MoveNext();
			}
			XYZ endPoint = detailLine.GeometryCurve.GetEndPoint(1);
			XYZ list = detailLine.GeometryCurve.GetEndPoint(0) - detailLine.GeometryCurve.GetEndPoint(1);
			XYZ xyz = AxisAssistFunc.RotateTo(list, 0.26179938779914941, XYZ.BasisZ);
			XYZ xyz2 = AxisAssistFunc.RotateTo(list, -0.26179938779914941, XYZ.BasisZ);
			XYZ ePoint = endPoint + xyz.Normalize() * num;
			DetailLine detailLine2 = YJKRevitTools.DrawDetailLine(uiApp.ActiveUIDocument.Document, endPoint, ePoint);
			elemSetDim.Insert(detailLine2);
			XYZ ePoint2 = endPoint + xyz2.Normalize() * num;
			DetailLine detailLine3 = YJKRevitTools.DrawDetailLine(uiApp.ActiveUIDocument.Document, endPoint, ePoint2);
			elemSetDim.Insert(detailLine3);
		}

		public static YJKWindowHandle hWndRevit;
	}
}
